Add self-correction loop: logs, call, and shot commands - #30
Merged
Conversation
The agent that builds applets could not tell when they broke: a widget compiles, then fails to load in the browser, crashes on render, or its server function throws — and nothing reaches the agent until the user complains. Close the loop with two legs (spec: docs/self-correction.md): - moi debug logs — an applet error journal under the new experimental `moi debug` command group. A per-workspace, in-memory ring buffer fed server-side (RPC failures, build failures) and by the browser (load failures, render crashes via the error boundary, window errors attributed by bundle-URL stack match, POSTed to /applet-log with a hostile-input guard). Identical errors dedup into a count; a successful rebuild clears the applet's standing entries; `moi bundle` ends with a nudge when errors remain on record. - moi call-server-fn — invoke one .server.ts function directly. Each invocation runs in an EPHEMERAL one-shot worker: spawn, single call, kill — fully isolated from the warm pool the widgets use, with the same env injection, module loading, timeout, and devalue wire format. Args as one JSON array; results render via Bun.inspect with duration. The moi-workspace skill grows a "Verify your work" section teaching the loop (bump to 0.6.0), with `moi debug` marked experimental. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
molefrog
force-pushed
the
claude/agent-self-correction-aegbzt
branch
from
July 17, 2026 09:12
7f037df to
174ab37
Compare
molefrog
commented
Jul 18, 2026
| - `moi refresh` — re-fetch widget/view data without rebuilding (use after you mutated data the | ||
| widgets read — DB rows, files, external API records — so the displayed values catch up) | ||
| - `moi call-server-fn <module>/<fn> '[args]'` — invoke a `.server.ts` function directly | ||
| (smoke test; see Verify your work) |
molefrog
commented
Jul 18, 2026
| widgets read — DB rows, files, external API records — so the displayed values catch up) | ||
| - `moi call-server-fn <module>/<fn> '[args]'` — invoke a `.server.ts` function directly | ||
| (smoke test; see Verify your work) | ||
| - `moi debug logs` — applet runtime errors on record (experimental; see Verify your work) |
Owner
Author
There was a problem hiding this comment.
Suggested change
| - `moi debug logs` — applet runtime errors on record (experimental; see Verify your work) | |
| - `moi debug logs` — applet runtime errors on record (experimental) |
Address PR #30 review: drop the "see Verify your work" cross-references from the CLI list, and rewrite the section (now "Debugging applets") so call-server-fn and debug logs are offered as feedback channels the agent can reach for, rather than a mandated verify-every-time checklist. The ambient signals (bundle footer nudge, always-on browser reporting) carry the discovery instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
Two upgrades to the window-error half of the applet journal: - Attribute 'error' events via ErrorEvent.filename first — a structured URL with no per-browser stack-format quirks, which also covers throws that carry no usable stack (`throw 'string'`). The stack-text scan stays as the fallback (handler threw inside vendor code) and as the only path for unhandled rejections, which have no filename. - Close the flood hole: the per-error cooldown keys on the message, so an error whose text varies each occurrence (timestamps, ids) bypassed it — and the server dedup — turning a tight throw loop into a POST storm. A global cap (30 reports/min, silent drops) bounds the total regardless of message shape. The URL matcher is extracted and unit-tested against bare filenames, Chrome/Firefox stack shapes, and near-miss URLs (vendor, rpc). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
molefrog
pushed a commit
that referenced
this pull request
Jul 18, 2026
Address PR #30 review: drop the "see Verify your work" cross-references from the CLI list, and rewrite the section (now "Debugging applets") so call-server-fn and debug logs are offered as feedback channels the agent can reach for, rather than a mandated verify-every-time checklist. The ambient signals (bundle footer nudge, always-on browser reporting) carry the discovery instead. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements the three-leg self-correction feedback loop for applets, allowing the agent to detect runtime failures, test server functions, and see what applets actually look like without waiting for user feedback.
Summary
Adds three new CLI commands (
moi logs,moi call,moi shot) that close the gap between successful builds and actual runtime behavior. The agent can now:moi logs) — query an in-memory error journal of applet runtime failuresmoi call) — invoke server functions directly through the same worker pool as browser RPCmoi shot) — render applets to PNG through a live workspace tabKey Changes
Server-side error journal (
server/applet-log.ts)build,load,render,window,rpcCLI commands (
server/cli.ts)moi logs [--json] [--clear]— display or clear the error journalmoi call <module>/<fn> '[args]'— invoke a server function with JSON arguments, returns devalue-encoded resultmoi shot widget|view <name>— screenshot an applet at its real grid size (or full panel for views)Browser-side error reporting (
client/lib/applet-log.ts)POST /api/workspaces/:id/applet-logwith per-error cooldown (5s) to prevent stormsApplet screenshot support (
client/lib/applet-shot.tsx,server/applet-shot.ts)modern-screenshotand measures content overflowControl port integration (
server/control.ts)sendScratch→ genericsendControlto handle multiple request typeslogs,call, andshotrequest typesmoi bundleoutput now nudges towardmoi logswhen errors are on recordType definitions (
lib/types.ts)AppletKind—'widget' | 'view'AppletLogSource—'build' | 'load' | 'render' | 'window' | 'rpc'AppletLogEntry— full journal entry shape with dedup countShotRequest/ShotResult— screenshot request/response typesGeneric relay utility (
server/relay.ts)createRelay<Res>scratchpad-relay.ts) and applet shots (applet-shot.ts)Error boundary updates (
client/components/WidgetErrorBoundary.tsx)kind(widget/view) andworkspaceIdfor attributiononErrorcallback for callers like applet shotsRPC error recording (
server/api.ts)moi callto surface issues before the browser sees themhttps://claude.ai/code/session_01M8rSCv39HrkfaH23tceb2q